<template>
  <el-container>
    <el-aside class="container-aside">
      <div class="components-list">
        <div class="widget-cate">基础字段</div>
        <ul>
          <li v-for="item in confList" :key="item.type" class="form-edit-widget-label" @click="btnClick(item.type)">{{ item.type }}</li>
        </ul>
        <div class="widget-cate">高级字段</div>
        <ul>
          <li v-for="item in superList" :key="item.type" class="form-edit-widget-label" @click="btnClick(item.type)">{{ item.type }}</li>
        </ul>
        <div class="widget-cate">操作</div>
        <div>
          <ul>
            <li class="form-edit-widget-label" @click="preview">预览效果</li>
            <li class="form-edit-widget-label" @click="previewData">预览数据</li>
            <li class="form-edit-widget-label" @click="exportData">导出数据</li>
          </ul>
        </div>
      </div>
      <!-- 预览效果dialog -->
      <el-dialog
        v-if="previewDialog"
        :visible.sync="previewDialog">
        <div v-if="formConf.formData.length == 0">
          <p>暂时还没有添加的表单</p>
          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="previewDialog = false">确定</el-button>
          </div>
        </div>
        <form-render
          v-if="formConf.formData.length !== 0"
          :form-render-conf="formConf"
          @submit="formBuilderSubmit"
          @cancel-submit="formBuilderCancelSubmit"/>
        <!-- 内部result dialog -->
        <el-dialog
          v-if="resultDialog"
          :visible.sync="resultDialog"
          width="30%"
          title="result"
          append-to-body>
          <p>{{ resultData }}</p>
          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="resultDialog = false">确定</el-button>
          </div>
        </el-dialog>
      </el-dialog>
      <!-- 预览数据 Dialog -->
      <el-dialog
        v-if="previewDataDialog"
        :visible.sync="previewDataDialog">
        <p>{{ formConf }}</p>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" @click="previewDataDialog = false">确定</el-button>
        </div>
      </el-dialog>
    </el-aside>
    <el-main>
      <el-form :label-width="formConf.config.width+'px'" :label-position="formConf.config.position" :size="formConf.config.size" class="dg-draggable-form">
        <p v-if="dgFormData.length == 0" class="no-form-item">点击左边按钮，添加表单</p>
        <div v-if="dgFormData.length > 0">
          <draggable :list="dgFormData" :group="{ name: 'people', animation: 150}" :no-transition-on-drag="true" @start="drag=true" @end="drag=false">
            <transition-group :name="!drag? 'list-complete' : null" :css="true">
              <confBuilder
                v-for="(conf,index) in dgFormData"
                :key="conf.id"
                :conf="conf"
                :index="index"
                @remove-form-item="removeFormItem"
                @show-form-item-conf="showFormItemConf"/>
            </transition-group>
          </draggable>
        </div>
      </el-form>
      <!-- 编辑表单dialog -->
      <el-dialog
        :visible.sync="confDialogDg"
        title="配置属性">
        <!-- p -->
        <el-form v-if="widget.type === 'p'" :inline="false" label-width="80px" label-position="left" size="mini">
          <el-form-item label="段落内容">
            <el-input v-model="widget.content" :row="2" type="textarea"/>
          </el-form-item>
          <el-form-item label="对齐方式">
            <el-radio-group v-model="widget.textAlign">
              <el-radio-button label="left">左对齐</el-radio-button>
              <el-radio-button label="center">居中对齐</el-radio-button>
              <el-radio-button label="right">右对齐</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="字体大小">
            <el-input-number v-model="widget.fontSize" :min="10" :max="30"/>
          </el-form-item>
          <el-form-item label="字体粗细">
            <el-radio-group v-model="widget.fontWeight">
              <el-radio-button label="normal">正常</el-radio-button>
              <el-radio-button label="bold">加粗</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="字体颜色">
            <el-color-picker v-model="widget.color"/>
          </el-form-item>
          <el-form-item label="可见">
            <el-switch
              v-model="widget.visible"
              active-color="#13ce66"
              inactive-color="#ff4949"/>
          </el-form-item>
        </el-form>
        <!-- 表单 -->
        <el-form v-if="widget.type !== 'p'" :inline="false" label-width="80px" label-position="left" size="mini">
          <el-form-item label="控件名称">
            <el-input v-model="widget.label" placeholder="请输入label"/>
          </el-form-item>
          <el-form-item label="name">
            <el-input v-model="widget.name" placeholder="name属性"/>
          </el-form-item>
          <el-form-item label="可见">
            <el-switch
              v-model="widget.visible"
              active-color="#13ce66"
              inactive-color="#ff4949"/>
          </el-form-item>
          <el-form-item label="禁用">
            <el-switch
              v-model="widget.disabled"
              active-color="#13ce66"
              inactive-color="#ff4949"/>
          </el-form-item>
          <el-form-item label="必填">
            <el-switch
              v-model="widget.required"
              active-color="#13ce66"
              inactive-color="#ff4949"/>
          </el-form-item>
          <el-form-item label="布局占位">
            <el-input-number
              v-model="widget.span"
              :min="1"
              :max="24"/>
          </el-form-item>
          <el-form-item v-if="widget.type == 'input'" label="验证">
            <el-row>
              <el-col :span="11" style="textAlign:center;">正则</el-col>
              <el-col :span="11" :offset="2" style="textAlign:center;">提示</el-col>
            </el-row>
            <el-row>
              <el-col :span="11">
                <el-input v-model="widget.regex.rule" style="width:100%;"></el-input>
              </el-col>
              <el-col :span="2" style="textAlign:center">-</el-col>
              <el-col :span="11">
                <el-input v-model="widget.regex.message" style="width:100%;"></el-input>
              </el-col>
            </el-row>
          </el-form-item>

           <el-row v-if="widget.type == 'select'" style="text-align: center">
            <span style="color:#409EFF; cursor:pointer; margin: 0 10px;" @click="unOptionUrl(widget.remote)">手动添加</span>
            <span style="color:#409EFF; cursor:pointer; margin: 0 10px;" @click="addOptionUrl(widget.remote)">远程添加</span>
          </el-row>
          <el-form-item :hidden="widget.remote" v-if="widget.options" label="选项">
            <span style="color:#409EFF; cursor:pointer;" @click="addOption">添加选项</span>
            <el-row>
              <el-col :span="10" style="textAlign:center;">value</el-col>
              <el-col :span="10" :offset="2" style="textAlign:center;">label</el-col>
            </el-row>
            <el-row v-for="(option,index) in widget.options" :key="index">
              <el-col :span="10">
                <el-input v-model="option.value" style="width:100%;" size="mini" />
              </el-col>
              <el-col :span="2" style="textAlign:center">-</el-col>
              <el-col :span="10">
                <el-input v-model="option.label" style="width:100%;" size="mini" />
              </el-col>
              <el-col :span="2" style="textAlign:center;">
                <i
                  class="el-icon-remove-outline"
                  style="color:#409EFF;cursor:pointer;"
                  @click="removeOption(index)"
                />
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item v-show="widget.remote" label="选项">
            <el-row>
              <el-row>
                <span style="color:#409EFF; cursor:pointer;" @click="addHeaders">添加header选项</span>
              </el-row>
              <el-row>
                <el-col :span="10" style="textAlign:center;">key</el-col>
                <el-col :span="10" :offset="2" style="textAlign:center;">value</el-col>
              </el-row>
              <el-row v-for="(header,index) in widget.headers" :key="index">
                <el-col :span="10">
                  <el-input v-model="header.key" style="width:100%;" size="mini" />
                </el-col>
                <el-col :span="2" style="textAlign:center">-</el-col>
                <el-col :span="10">
                  <el-input v-model="header.value" style="width:100%;" size="mini" />
                </el-col>
                <el-col :span="2" style="textAlign:center;">
                  <i
                    class="el-icon-remove-outline"
                    style="color:#409EFF;cursor:pointer;"
                    @click="removeHeaders(index)"
                  />
                </el-col>
              </el-row>
              <el-input v-model="widget.url" placeholder="请求地址" />
            </el-row>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="confDialogDg = false">取 消</el-button>
          <el-button type="primary" @click="commitConf">确 定</el-button>
        </div>
      </el-dialog>
    </el-main>
    <el-aside class="container-aside">
      <el-form label-position="top" size="mini">
        <el-form-item
          label="表单字段宽度">
          <el-input-number v-model="formConf.config.width" size="mini"/>
        </el-form-item>
        <el-form-item
          label="表单字段位置">
          <el-radio-group
            v-model="formConf.config.position"
            size="mini">
            <el-radio-button label="left">左边</el-radio-button>
            <el-radio-button label="right">右边</el-radio-button>
            <el-radio-button label="top">上边</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item
          label="表单尺寸大小">
          <el-radio-group
            v-model="formConf.config.size"
            size="mini">
            <el-radio-button label="medium">正常</el-radio-button>
            <el-radio-button label="small">较小</el-radio-button>
            <el-radio-button label="mini">超小</el-radio-button>
          </el-radio-group>
        </el-form-item>
      </el-form>
    </el-aside>
  </el-container>
</template>
<script>
import confBuilder from './confBuilder.vue'
import formRender from './formRender.vue'
import { confList, superList } from '../control'
import { getRandomNumber,getOptions } from '../utils/index.js'
// import { getOptions } from './mixins'
import draggable from 'vuedraggable'

export default {
  name: 'DgFormBuilder',
  components: {
    confBuilder,
    draggable,
    formRender
  },
  props: {
    formBuilderConf: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      previewDialog: false,
      previewDataDialog: false,
      resultDialog: false,
      dgFormData: [],  // 组件内部的formData
      drag: false,
      confList: confList,
      superList,
      formConf: {
        config: {
          width: 70,
          position: 'left',
          size: 'mini'
        },
        formData: []
      },
      resultData: {},
      widget: {},
      confDialogDg: false,
      formItemIndex: null
    }
  },
  watch: {
    formBuilderConf: {
      handler: function(val) {
        this.formConf.config = Object.assign({}, this.formConf.config, val.config)
        this.dgFormData = JSON.parse(JSON.stringify(val['formData']))
      },
      deep: true
    }
  },
  beforeMount: function() {
    // 如果formBuilderConf有数据，则覆盖formConf中的数据
    if (this.formBuilderConf) {
      this.formConf.config = Object.assign({}, this.formConf.config, this.formBuilderConf.config)
      for (var i in this.formBuilderConf['formData']) {
        this.dgFormData.push(this.formBuilderConf['formData'][i])
      }
    }
  },
  methods: {
    addOptionUrl() {
      this.widget.remote = true
    },
    unOptionUrl() {
      this.widget.remote = false
    },
    preview() {
      this.$set(this.formConf, 'formData', this.dgFormData)
      this.previewDialog = true
    },
    previewData() {
      this.$set(this.formConf, 'formData', this.dgFormData)
      this.previewDataDialog = true
    },
    formBuilderSubmit: function(formData) {
      this.resultData = Object.assign({}, this.resultData, formData)
      this.resultDialog = true
    },
    formBuilderCancelSubmit: function() {
      this.previewDialog = false
    },
    exportData: function() {
      this.$set(this.formConf, 'formData', this.dgFormData)
      this.$emit('export', this.formConf)
    },
    confChange: function(conf, index) {
      this.dgFormData.splice(index, 1, conf)
    },
    removeFormItem: function(index) {
      this.dgFormData.splice(index, 1)
    },
    showFormItemConf: function(index) {
      this.formItemIndex = index
      this.confDialogDg = true
      var widget = JSON.stringify(this.dgFormData[index])
      this.widget = JSON.parse(widget)
    },
    addOption() {
      var random = getRandomNumber()
      this.widget.options.push({ label: '新增选项', value: 'option-' + random })
    },
    addHeaders() {
      this.widget.headers.push({
        key: 'key',
        value: 'value'
      })
    },
    removeHeaders(index) {
      this.widget.headers.splice(index, 1)
    },
    removeOption(index) {
      this.widget.options.splice(index, 1)
    },
    commitConf() {
      this.confDialogDg = false
      var index = this.formItemIndex
      this.dgFormData.splice(index, 1, this.widget)

      var newFormConf = JSON.parse(JSON.stringify(this.formConf))
      newFormConf['formData'] = JSON.parse(JSON.stringify(this.dgFormData))
      this.$emit('update:formBuilderConf', newFormConf)
    },
    btnClick(type) {
      var conf
      var normalInput = ['input', 'date']
      var superInput = ['select', 'radio', 'checkbox']
      var otherInput = ['p']
      // 不同表单类型添加id和options
      var randomNumber = getRandomNumber()
      if (normalInput.indexOf(type) > -1) {
        confList[type]['id'] = randomNumber
        conf = JSON.parse(JSON.stringify(confList[type]))
      } else if (superInput.indexOf(type) > -1) {
        confList[type]['id'] = randomNumber
        conf = Object.assign({}, confList[type])
        conf['options'] = getOptions()
      } else if (otherInput.indexOf(type) > -1) {
        superList[type]['id'] = randomNumber
        conf = Object.assign({}, superList[type])
      }
      conf['name'] = type + '-' + randomNumber
      this.dgFormData.push(conf)
    }
  }
}
</script>

<style scoped>
.container-aside{
  width:200px;
}
.components-list{
  padding:8px 0;
  width:100%;
}
.no-form-item{
  font-size:13px;
  color:#ccc;
}
.components-list .widget-cate{
  padding:8px 12px;
  font-size:13px;
}
.components-list ul{
  position:relative;
  margin:0;
  padding:0 10px 10px;
  overflow:hidden;
  box-sizing: border-box;
}
ul li{
  margin:0;
  padding:0;
  list-style:none;
  box-sizing:border-box;
}
.form-edit-widget-label{
  padding-left:10px;
  font-size:12px;
  display:block;
  width:48%;
  line-height:26px;
  position: relative;
  float:left;
  left:0;
  overflow:hidden;
  text-overflow: ellipsis;
  white-space:nowrap;
  color:#333;
  border:1px solid #f4f6fc;
  margin:1%;
  /* cursor: move; */
  cursor:pointer;
}
.dg-draggable-form *{
  -webkit-user-drag: element;
}
.form-edit-widget-label:hover{
  color:#409eff;
  border:1px dashed #409eff;
}
.list-complete-enter-active {
  overflow: hidden;
  transition: all 1s;
}
.list-complete-leave-active {
  margin-top: 0px;
  overflow: hidden;
  transition: all 1s;
}
.list-complete-enter, .list-complete-leave-to {
  height: 0px;
  opacity: 0;
  padding: 0px;
  margin-top: 0px;
  overflow: hidden;
}
</style>
